home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / Snippets / Networking / Neighborhood Watch / Talker.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-01  |  18.6 KB  |  1,000 lines  |  [TEXT/MPS ]

  1. #include <Stdio.h>
  2. #include <Memory.h>
  3. #include <Types.h>
  4. #include <CursorCtl.h>
  5. #include <AppleTalk.h>
  6. #include <Packages.h>
  7. #include <Events.h>
  8. #include <SysEqu.h>
  9. #include <Desk.h>
  10. #include <Devices.h>
  11. #include <Errors.h>
  12. #include <Fonts.h>
  13. #include <Menus.h>
  14. #include <ToolUtils.h>
  15. #include <Events.h>
  16. #include <Resources.h>
  17. #include <OSEvents.h>
  18. #include <Scrap.h>
  19.  
  20.  
  21.  
  22. /*
  23.                     © Copyright 1991 Apple Computer, By Ricardo Batista
  24.  
  25.     This is a quick and dirty application to chat over the network using
  26.     
  27.         
  28.         
  29.     Written by Ricardo Batista. 1/31/91
  30. */
  31.  
  32.  
  33. #define        appleMenu            128
  34. #define        fileMenu            129
  35. #define        editMenu            130
  36. #define        setupMenu            131
  37.  
  38.  
  39. #define        quitItem            1
  40.  
  41. #define        undoItem            1
  42. #define        cutItem                3
  43. #define        copyItem            4
  44. #define        pasteItem            5
  45. #define        clearItem            6
  46.  
  47. #define        configureItem        1
  48.  
  49. #define        okItem            1
  50. #define        cancelItem        2
  51.  
  52. #define        MAXADDRBLOCKS        100
  53.  
  54. #define        LOOKUPBUFSIZE        20000
  55.  
  56. pascal void InitDDPListener(ATDDPRec *ddp);
  57. pascal void DDPListener(void);
  58.  
  59. void DoAbout(void);
  60. void NewMessage(void);
  61. void SetMenus(void);
  62. void AnalizeKeys(void);
  63. Boolean Working(void);
  64. Boolean DoCommand(long mResult);
  65. Boolean HandleMouseDowns(void);
  66. void Configure(void);
  67. void ShowStatus(void);
  68. void CleanUp(void);
  69. void AdjustTextScrollBar();
  70. void Message(char *mess);
  71. short DoDDP(char *st);
  72. short DoRegName(void);
  73. void CleanTalk(void);
  74. Boolean Setup(void);
  75. void Names(void);
  76. short myNBPExtract(char *buffer,int howMany,int which,EntityName *Name,AddrBlock *Addr);
  77.  
  78.  
  79. char ourName[60];
  80. EventRecord myEvent;
  81. Boolean commandK, shiftK, optionK;
  82. Boolean inFront;
  83. short err;
  84. MenuHandle myMenu[5];
  85. WindowPtr textWindow = 0L;
  86. TEHandle textTE = 0L;
  87. ControlHandle textScrollBar = 0L;
  88. WindowRecord wRec;
  89.  
  90. short mpp = 0, socket = 0;
  91. NamesTableEntry *NTPtr = 0L;
  92. MPPParamBlock p;
  93. ATDDPRec ddp;
  94. char buffer[1000];
  95. AddrBlock *users;
  96.  
  97.  
  98.  
  99. void main()
  100. {
  101.     short err, len;
  102.     char *copyright = {"© 1991 Apple Computer, Inc.  By Ricardo Batista"};
  103.     char st[256];
  104.     
  105.     if (!Setup())
  106.         return;
  107.     err = OpenDriver("\p.MPP",&mpp);
  108.     if (err) {
  109.         Message("\pAppleTalk is not available");
  110.         return;
  111.     }
  112.     err = DoRegName();
  113.     Names();
  114.     BlockMove("\pEntering the network...",st,30L);
  115.     len = ourName[0];
  116.     BlockMove(&ourName[1], &st[st[0] + 1], (long) len);
  117.     st[0] += len;
  118.     err = DoDDP(st);
  119.     if (err)
  120.         Message("\pError writing to network.");
  121.     while (Working())
  122.         ;
  123.     BlockMove("\pLeaving the network...",st,30L);
  124.     len = ourName[0];
  125.     BlockMove(&ourName[1], &st[st[0] + 1], (long) len);
  126.     st[0] += len;
  127.     err = DoDDP(st);
  128.     CleanTalk();
  129. }
  130.  
  131.  
  132.  
  133.  
  134.  
  135. Boolean Setup(void)
  136. {
  137.     short counter;
  138.     Rect box, bounds;
  139.     
  140.     for (counter = 0; counter < 10; counter++)
  141.         MoreMasters();
  142.     InitGraf(&qd.thePort);
  143.     InitFonts();
  144.     InitWindows();
  145.     TEInit();
  146.     InitMenus();
  147.     InitDialogs(0L);
  148.     DrawMenuBar();
  149.     FlushEvents(everyEvent,0L);
  150.     InitCursor();
  151.     MaxApplZone();
  152.     SetCursor(*GetCursor(watchCursor));
  153.     InitAllPacks();
  154.     SetMenus();
  155.     box.top = 40;
  156.     box.left = 10;
  157.     box.right = 500;
  158.     box.bottom = 300;
  159.     textWindow = NewWindow((Ptr) &wRec,&box,"\pNeighborhood Watch  by Ricardo Batista",1,documentProc,
  160.                     (WindowPtr) -1L,0,0L);
  161.     if (!textWindow)
  162.         return(false);
  163.     SetPort(textWindow);
  164.     TextSize(9);
  165.     TextFont(1);
  166.     box = textWindow->portRect;
  167.     box.left = 5;
  168.     box.bottom -= 16;
  169.     box.right -= 16;
  170.     bounds.top = box.top;
  171.     bounds.left = 5;
  172.     bounds.right = box.right;
  173.     bounds.bottom = 2000;
  174.     textTE = TENew(&bounds,&box);
  175.     if (!textTE)
  176.         return(false);
  177.     box = textWindow->portRect;
  178.     box.top--;
  179.     box.right -= 15;
  180.     bounds.top = box.top;
  181.     bounds.left = box.right;
  182.     bounds.right = bounds.left + 16;
  183.     bounds.bottom = box.bottom - 14;
  184.     textScrollBar = NewControl(textWindow,&bounds,"\p",1,1,1,1,scrollBarProc,(long) textTE);
  185.     BeginUpdate(textWindow);
  186.     EndUpdate(textWindow);
  187.     DrawGrowIcon(textWindow);
  188.     TEActivate(textTE);
  189.     AdjustTextScrollBar();
  190.     inFront = true;
  191.     ddp.abResult = 1;
  192.     ddp.ddpActCount = 0;
  193.     ddp.ddpReqCount = 586;
  194.     ddp.ddpDataPtr = buffer;
  195.     users = (AddrBlock*) NewPtrClear(sizeof(AddrBlock) * MAXADDRBLOCKS);
  196.     return(true);
  197. }
  198.  
  199.  
  200.  
  201.  
  202.  
  203.  
  204. void CleanTalk()
  205. {
  206.     if (socket && NTPtr) {
  207.         p.NBPntQElPtr = (Ptr) &(NTPtr->nt.entityData[0]);
  208.         err = PRemoveName(&p,false);
  209.         DisposPtr((Ptr) NTPtr);
  210.         p.DDPsocket = (unsigned char) socket;
  211.         err = PCloseSkt(&p,false);
  212.         if (err)
  213.             Message("\pCould not close socket.");
  214.     }
  215.     if (textWindow)
  216.         CloseWindow(textWindow);
  217.     if (textTE)
  218.         TEDispose(textTE);
  219. }
  220.  
  221.  
  222.  
  223.  
  224.  
  225. void SetMenus()
  226. {
  227.     char appleStr[2];
  228.     
  229.     appleStr[0] = 1;
  230.     appleStr[1] = 0x14;
  231.     myMenu[appleMenu - 128] = NewMenu(appleMenu,appleStr);
  232.     myMenu[fileMenu - 128] = NewMenu(fileMenu,"\pFile");
  233.     myMenu[editMenu - 128] = NewMenu(editMenu,"\pEdit");
  234.     myMenu[setupMenu - 128] = NewMenu(setupMenu,"\pTalk");
  235.     
  236.     AppendMenu(myMenu[appleMenu - 128],"\pAbout Neighborhood Watch...;(-");
  237.     AddResMenu(myMenu[appleMenu - 128],'DRVR');
  238.     
  239.     AppendMenu(myMenu[fileMenu - 128],"\pQuit/Q");
  240.     AppendMenu(myMenu[editMenu - 128],"\pUndo;(-;Cut/X;Copy/C;Paste/V;Clear");
  241.     AppendMenu(myMenu[setupMenu - 128],"\pSend A Message/M");
  242.     InsertMenu(myMenu[appleMenu - 128],0);
  243.     InsertMenu(myMenu[fileMenu - 128],0);
  244.     InsertMenu(myMenu[editMenu - 128],0);
  245.     InsertMenu(myMenu[setupMenu - 128],0);
  246.     DrawMenuBar();
  247. }
  248.  
  249.  
  250.  
  251.  
  252.  
  253.  
  254.  
  255.  
  256. short DoRegName()
  257. {
  258.     EntityName name;
  259.     short err, len;
  260.     short index;
  261.     StringHandle H;
  262.     
  263.     H = GetString(-16096);
  264.     if (H) {
  265.         LoadResource((Handle) H);
  266.         HLock((Handle) H);
  267.         BlockMove((Ptr) *H, ourName, 40L);
  268.         HUnlock((Handle) H);
  269.         ReleaseResource((Handle) H);
  270.     }
  271.     else {
  272.         ourName[0] = 1;
  273.         ourName[1] = '?';
  274.     }
  275.     p.MPPioCompletion = 0L;
  276.     p.MPPioRefNum = mpp;
  277.     p.DDPsocket = 0;
  278.     p.DDPlistener = (Ptr) StripAddress((Ptr) (ProcPtr) DDPListener);
  279.     err = POpenSkt(&p,true);
  280.     while (p.MPPioResult == 1)
  281.         ;
  282.     if (err) {
  283.         Message("\pCould not open AppleTalk socket !!!");
  284.         return(err);
  285.     }
  286.     socket = p.DDPsocket;
  287.     name.zoneStr[0] = 1;
  288.     name.zoneStr[1] = '*';
  289.     BlockMove("\pNeighborhood Watch",name.typeStr, 20L);
  290.     len = sizeof(NamesTableEntry);
  291.     
  292.     NTPtr = (NamesTableEntry*) NewPtrClear(len);
  293.     if (!NTPtr)
  294.         return(MemErr);
  295.     NTPtr->nt.nteAddress.aSocket = socket;
  296.     p.NBPinterval = 3;
  297.     p.NBPcount = 3;
  298.     p.NBPverifyFlag = true;
  299.     p.NBPntQElPtr = (Ptr) NTPtr;
  300.     BlockMove(ourName,&(NTPtr->nt.entityData[0]),33L);
  301.     index = ourName[0] + 1;
  302.     BlockMove(name.typeStr,&(NTPtr->nt.entityData[index]),33L);
  303.     index += name.typeStr[0] + 1;
  304.     BlockMove(name.zoneStr,&(NTPtr->nt.entityData[index]),33L);
  305.     err = PRegisterName(&p,true);
  306.     while (p.MPPioResult == 1)
  307.         ;
  308.     err = p.MPPioResult;
  309.     while (err == nbpDuplicate) {
  310.         ourName[0]++;
  311.         ourName[ourName[0]] = '1';
  312.         BlockMove(ourName,&(NTPtr->nt.entityData[0]),33L);
  313.         index = ourName[0] + 1;
  314.         BlockMove(name.typeStr,&(NTPtr->nt.entityData[index]),33L);
  315.         index += name.typeStr[0] + 1;
  316.         BlockMove(name.zoneStr,&(NTPtr->nt.entityData[index]),33L);
  317.         err = PRegisterName(&p,true);
  318.         while (p.MPPioResult == 1)
  319.             ;
  320.         err = p.MPPioResult;
  321.     }
  322.     if (err)
  323.         Message("\pCould not register name in network.");
  324.     InitDDPListener(&ddp);
  325.     return(noErr);
  326. }
  327.  
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343.  
  344. // I tried making network wide broadcasts, but seems like the FX didn't like opening static sockets,
  345. // there was no problem with the SE30 and Portable, but the FX was a problem...
  346.  
  347.  
  348.  
  349. short DoDDP(char *st)
  350. {
  351.     MPPParamBlock p;
  352.     short err = 0;
  353.     WDSElement wds[4];
  354.     unsigned char header[20];
  355.     register short counter;
  356.     
  357.     wds[2].entryLength = 0;
  358.     wds[2].entryPtr = 0L;
  359.     wds[3].entryLength = 0;
  360.     wds[3].entryPtr = 0L;
  361.     wds[1].entryPtr = st;
  362.     wds[1].entryLength = st[0] + 1;
  363.     p.MPPioResult = 1;
  364.     p.MPPioCompletion = 0L;
  365.     p.MPPioRefNum = mpp;
  366.     p.DDPchecksumFlag = false;
  367.     p.DDPsocket = socket;
  368.     p.DDPwdsPointer = (Ptr) wds;
  369.     wds[0].entryPtr = &header[1];
  370.     wds[0].entryLength = 16;
  371.     
  372.     header[16] = 44;         // Type;
  373.     for (counter = 0; counter < MAXADDRBLOCKS;) {
  374.         BlockMove((Ptr) &(users[counter].aNet),&header[8],2L);
  375.         header[14] = users[counter].aSocket;     //  Socket;
  376.         header[12] = users[counter].aNode;        // Node
  377.         err = PWriteDDP(&p,true);
  378.         while (p.MPPioResult == 1)
  379.             ;
  380.         counter++;
  381.         if (users[counter].aNet == 0)
  382.             counter = MAXADDRBLOCKS + 1;
  383.     }
  384.     if (!err)
  385.         err = p.MPPioResult;
  386.     return(err);
  387. }
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400. void UpdateTextWindow()
  401. {
  402.     GrafPtr savePort;
  403.     Rect box;
  404.     
  405.     GetPort(&savePort);
  406.     SetPort(textWindow);
  407.     BeginUpdate(textWindow);
  408.     box = textWindow->portRect;
  409.     TEUpdate(&box,textTE);
  410.     EndUpdate(textWindow);
  411.     DrawGrowIcon(textWindow);
  412.     SetPort(savePort);
  413. }
  414.  
  415.  
  416.  
  417.  
  418.  
  419.  
  420. void AnalizeKeys()
  421. {
  422.     if (myEvent.modifiers & cmdKey)
  423.         commandK = true;
  424.     else
  425.         commandK = false;
  426.     if (myEvent.modifiers & shiftKey)
  427.         shiftK = true;
  428.     else
  429.         shiftK = false;
  430.     if (myEvent.modifiers & optionKey)
  431.         optionK = true;
  432.     else
  433.         optionK = false;
  434. }
  435.  
  436.  
  437.  
  438.  
  439.  
  440. Boolean Working()
  441. {
  442.     register char theChar;
  443.     register Boolean event;
  444.     WindowPtr w;
  445.     GrafPtr savePort;
  446.     Rect box;
  447.     Point mouse;
  448.     short lines;
  449.     register long counter;
  450.     
  451.     if (ddp.abResult == 0) {
  452.         Message(buffer);
  453.         ddp.abResult = 1;
  454.         for (counter = 0; counter < MAXADDRBLOCKS; counter++) {
  455.             if ((users[counter].aNet == 0) && (users[counter].aNode == 0)) {
  456.                 users[counter] = ddp.ddpAddress;
  457.                 counter = MAXADDRBLOCKS + 1;
  458.                 Message("\pA new user has been recorded.");
  459.             }
  460.             else {
  461.                 if ((ddp.ddpAddress.aNet == users[counter].aNet) && 
  462.                                 (ddp.ddpAddress.aNode == users[counter].aNode))
  463.                         counter = MAXADDRBLOCKS + 1;
  464.             }
  465.         }
  466.     }
  467.     event = GetNextEvent(everyEvent,&myEvent);
  468.     AnalizeKeys();
  469.     w = FrontWindow();
  470.     if ((w == textWindow) && inFront && textTE) {
  471.         GetPort(&savePort);
  472.         SetPort(textWindow);
  473.         TEIdle(textTE);
  474.         box = w->portRect;
  475.         GetMouse(&mouse);
  476.         box.right -= 16;
  477.         box.bottom -= 16;
  478.         if (PtInRect(mouse,&box))
  479.             SetCursor(*(GetCursor(iBeamCursor)));
  480.         else
  481.             InitCursor();
  482.         SetPort(savePort);
  483.     }
  484.     if (event) {
  485.         switch (myEvent.what) {
  486.             case app4Evt:
  487.                 if (myEvent.modifiers & 128)
  488.                     inFront = true;
  489.                 else
  490.                     inFront = false;
  491.                 break;
  492.             case activateEvt:
  493.                 w = (WindowPtr) myEvent.message;
  494.                 if (myEvent.modifiers & activeFlag) {
  495.                     if (w == textWindow)
  496.                         TEActivate(textTE);
  497.                 }
  498.                 else {
  499.                     if (w == textWindow)
  500.                         TEDeactivate(textTE);
  501.                 }
  502.                 break;
  503.             case keyDown:
  504.             case autoKey:
  505.                 theChar =  myEvent.message & charCodeMask;
  506.                 if (commandK) {
  507.                     if (!DoCommand(MenuKey(theChar)))
  508.                         return(false);
  509.                 }
  510.                 else {
  511.                     w = FrontWindow();
  512.                     if (w == textWindow) {
  513.                         lines = (**textTE).nLines;
  514.                         TEKey(theChar,textTE);
  515.                         if (lines != (**textTE).nLines)
  516.                             AdjustTextScrollBar();
  517.                     }
  518.                 }
  519.                 break;
  520.             case updateEvt:
  521.                 w = (WindowPtr) myEvent.message;
  522.                 if (w == textWindow)
  523.                     UpdateTextWindow();
  524.                 break;
  525.             case mouseDown:
  526.                 if (!HandleMouseDowns())
  527.                     return(false);
  528.                 break;
  529.             default:
  530.                 break;
  531.         }
  532.     }
  533.     return(true);
  534. }
  535.  
  536.  
  537.  
  538.  
  539.  
  540.  
  541.  
  542.  
  543.  
  544.  
  545. pascal void CtlAction(theControl, part)
  546. ControlHandle theControl;
  547. short part;
  548. {
  549.     TEHandle TE;
  550.     short newValue, value, v, max;
  551.     
  552.     TE = (TEHandle) GetCRefCon(theControl);
  553.     max = GetCtlMax(theControl);
  554.     v = (**TE).lineHeight;
  555.     newValue = value = GetCtlValue(theControl);
  556.     if (part == inPageUp) {
  557.         newValue -= 12;
  558.         if (newValue < 1)
  559.             newValue = 1;
  560.         SetCtlValue(theControl,newValue);
  561.     }
  562.     if (part == inPageDown) {
  563.         newValue += 12;
  564.         if (newValue > max)
  565.             newValue = max;
  566.         SetCtlValue(theControl,newValue);
  567.     }
  568.     if (part == inUpButton) {
  569.         newValue--;
  570.         if (newValue < 1)
  571.             newValue = 1;
  572.         SetCtlValue(theControl,newValue);
  573.     }
  574.     if (part == inDownButton) {
  575.         newValue++;
  576.         if (newValue > max)
  577.             newValue = max;
  578.         SetCtlValue(theControl,newValue);
  579.     }
  580.     if (value != newValue)
  581.         TEScroll(0,(value - newValue) * v,TE);
  582. }
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.  
  590.  
  591. void HandleMouseInText()
  592. {
  593.     short where;
  594.     ControlHandle whichControl;
  595.     short value, oldValue;
  596.     short v;
  597.     Rect box;
  598.     
  599.     SetPort(textWindow);
  600.     GlobalToLocal(&myEvent.where);
  601.     where = FindControl(myEvent.where,textWindow,&whichControl);
  602.     switch (where) {
  603.         case inUpButton:
  604.         case inDownButton:
  605.         case inPageUp:
  606.         case inPageDown:
  607.             TrackControl(whichControl,myEvent.where,(ProcPtr) CtlAction);
  608.             break;
  609.         case inThumb:
  610.             v = (**(textTE)).lineHeight;
  611.             oldValue = GetCtlValue(whichControl);
  612.             if (TrackControl(whichControl,myEvent.where,0L)) {
  613.                 value = GetCtlValue(whichControl);
  614.                 if (value != oldValue) {
  615.                     TEScroll(0,(oldValue - value) * v,textTE);
  616.                 }
  617.             }
  618.             break;
  619.         case 0:
  620.             box = (**(textTE)).viewRect;
  621.             if (PtInRect(myEvent.where,&box))
  622.                 TEClick(myEvent.where,shiftK,textTE);
  623.             break;
  624.         default:
  625.             break;
  626.     }
  627. }
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634. void AdjustTextScrollBar()
  635. {
  636.     short lines;
  637.     short v;
  638.     short top, bottom;
  639.     
  640.     lines = (**textTE).nLines;
  641.     v = (**textTE).lineHeight;
  642.     top = (**textTE).viewRect.top;
  643.     bottom = (**textTE).viewRect.bottom;
  644.     bottom -= top + 10;
  645.     lines -= bottom / v;
  646.     if (lines < 1)
  647.         lines = 1;
  648.     if (lines > 1)
  649.         lines++;
  650.     SetCtlMax(textScrollBar,lines);
  651.     if (lines > 1)
  652.         HiliteControl(textScrollBar,0);
  653.     else
  654.         HiliteControl(textScrollBar,255);
  655. }
  656.  
  657.  
  658.  
  659.  
  660.  
  661. Boolean DoCommand(mResult)
  662. long mResult;
  663. {
  664.     register short theItem;
  665.     char st[250];
  666.     
  667.     theItem = LoWord(mResult);
  668.     switch (HiWord(mResult)) {
  669.         case appleMenu:
  670.                 GetItem(myMenu[0],theItem,st);
  671.                 if (theItem > 2)
  672.                     OpenDeskAcc(st);
  673.                 else
  674.                     DoAbout();
  675.                 break;
  676.         case fileMenu:
  677.                 switch (theItem) {
  678.                     case quitItem:
  679.                         return(false);
  680.                         break;
  681.                     default:
  682.                         break;
  683.                 }
  684.                 break;
  685.         case editMenu:
  686.                 if (!SystemEdit(theItem -1)) {
  687.                     switch (theItem) {
  688.                         case undoItem:
  689.                             break;
  690.                         case cutItem:
  691.                             if (textTE) {
  692.                                 TECut(textTE);
  693.                                 AdjustTextScrollBar();
  694.                             }
  695.                             ZeroScrap();
  696.                             TEToScrap();
  697.                             break;
  698.                         case copyItem:
  699.                             if (textTE)
  700.                                 TECopy(textTE);
  701.                             ZeroScrap();
  702.                             TEToScrap();
  703.                             break;
  704.                         case pasteItem:
  705.                             TEFromScrap();
  706.                             if (textTE) {
  707.                                 TEPaste(textTE);
  708.                                 AdjustTextScrollBar();
  709.                             }
  710.                             break;
  711.                         case clearItem:
  712.                             if (textTE) {
  713.                                 TEDelete(textTE);
  714.                                 AdjustTextScrollBar();
  715.                             }
  716.                             break;
  717.                         default:
  718.                             break;
  719.                     }
  720.                 }
  721.                 break;
  722.         case setupMenu:
  723.                 if (theItem == configureItem)
  724.                     NewMessage();
  725.                 break;
  726.             default:
  727.                 break;
  728.     }
  729.     HiliteMenu(0);
  730.     return(true);
  731. }
  732.  
  733.  
  734.  
  735.  
  736.  
  737.  
  738.  
  739.  
  740.  
  741. Boolean HandleMouseDowns()
  742. {
  743.     WindowPtr whichWindow;
  744.     Rect box;
  745.     long new;
  746.     short v, h;
  747.     
  748.     switch (FindWindow(myEvent.where,&whichWindow)) {
  749.         case inSysWindow:
  750.             SystemClick(&myEvent,whichWindow);
  751.             break;
  752.         case inMenuBar:
  753.             return(DoCommand(MenuSelect(myEvent.where)));
  754.             break;
  755.         case inGrow:
  756.             SetRect(&box,160,100,600,600);
  757.             new = GrowWindow(whichWindow,myEvent.where,&box);
  758.             if (new) {
  759.                 v = HiWord(new);
  760.                 h = LoWord(new);
  761.                 SetPort(whichWindow);
  762.                 SizeWindow(whichWindow,h,v,true);
  763.                 EraseRect(&(whichWindow->portRect));
  764.                 InvalRect(&(whichWindow->portRect));
  765.                 if (whichWindow == textWindow) {
  766.                     MoveControl(textScrollBar,h - 15,0);
  767.                     SizeControl(textScrollBar,16,v - 15);
  768.                     HLock((Handle) textTE);
  769.                     (**textTE).viewRect.right = h - 15;
  770.                     (**textTE).viewRect.bottom = v - 15;
  771.                     (**textTE).destRect.right = h - 15;
  772.                     HUnlock((Handle) textTE);
  773.                     TECalText(textTE);
  774.                     AdjustTextScrollBar();
  775.                 }
  776.             }
  777.             break;
  778.         case inGoAway:
  779.             if (!TrackGoAway(whichWindow,myEvent.where))
  780.                 break;
  781.             break;
  782.         case inDrag:
  783.             if (commandK || (FrontWindow() == whichWindow))
  784.                 DragWindow(whichWindow,myEvent.where,&qd.screenBits.bounds);
  785.             else {
  786.                 SelectWindow(whichWindow);
  787.                 SetPort(whichWindow);
  788.             }
  789.             break;
  790.         case inContent:
  791.              if (whichWindow != FrontWindow()) {
  792.                 SelectWindow(whichWindow);
  793.                 SetPort(whichWindow);
  794.             }
  795.             else {
  796.                 if (whichWindow == textWindow)
  797.                     HandleMouseInText();
  798.             }
  799.             break;
  800.         default:
  801.             break;
  802.     }
  803.     return(true);
  804. }
  805.  
  806.  
  807.  
  808.  
  809.  
  810.  
  811. void NewMessage(void)
  812. {
  813.     short err;
  814.     char st[256], mess[256];
  815.     GrafPtr savePort;
  816.     DialogPtr aDialog;
  817.     short item;
  818.     Handle H;
  819.     Rect box;
  820.     DialogRecord d;
  821.     
  822.     mess[0] = 0;
  823.     BlockMove(ourName, st, 40L);
  824.     st[0]++;
  825.     st[st[0]] = ':';
  826.     st[0]++;
  827.     st[st[0]] = ' ';
  828.     GetPort(&savePort);
  829.     aDialog = GetNewDialog(128, (Ptr) &d, (WindowPtr) -1L);
  830.     if (aDialog) {
  831.         SetPort(aDialog);
  832.         GetDItem(aDialog, okItem, &item, &H, &box);
  833.         PenSize(3,3);
  834.         InsetRect(&box, -5, -5);
  835.         FrameRoundRect(&box, 16, 16);
  836.         PenNormal();
  837.         item = 0;
  838.         while ((item != okItem) && (item != cancelItem))
  839.             ModalDialog(0L, &item);
  840.         if (item == okItem) {
  841.             GetDItem(aDialog, 3, &item, &H, &box);
  842.             GetIText(H, mess);
  843.             item = okItem;
  844.         }
  845.         CloseDialog(aDialog);
  846.     }
  847.     SetPort(savePort);
  848.     if (item == okItem) {
  849.         BlockMove(&mess[1], &st[st[0] + 1], (long) ((short) mess[0]));
  850.         st[0] += mess[0];
  851.         err = DoDDP(st);
  852.         if (err)
  853.             Message("\pError sending packet. Destination not found.");
  854.     }
  855. }
  856.  
  857.  
  858.  
  859.  
  860. void DoAbout()
  861. {
  862.     Message("\pThis is a quick and dirty application by Ricardo Batista.");
  863.     Message("\pAnyone in the network with this same application is able to");
  864.     Message("\preceive messages by others using this application.");
  865.     Message("\p© Copyright 1991 Apple Computer, Inc.  All Rights Reserved.");
  866.     Message("\p");
  867. }
  868.  
  869.  
  870.  
  871.  
  872.  
  873.  
  874.  
  875.  
  876. void Message(char *mess)
  877. {
  878.     long len;
  879.     GrafPtr savePort;
  880.     char st[40];
  881.     unsigned long t;
  882.     
  883.     GetDateTime(&t);
  884.     GetPort(&savePort);
  885.     SetPort(textWindow);
  886.     IUTimeString((long) t, true,st);
  887.     while (st[0] < 14) {
  888.         st[0]++;
  889.         st[st[0]] = ' ';
  890.     }
  891.     len = st[0];
  892.     TEInsert(&st[1],len,textTE);
  893.     IUDateString((long) t, shortDate ,st);
  894.     while (st[0] < 14) {
  895.         st[0]++;
  896.         st[st[0]] = ' ';
  897.     }
  898.     len = st[0];
  899.     TEInsert(&st[1],len,textTE);
  900.     len = mess[0];
  901.     TEInsert(&mess[1],len,textTE);
  902.     TEKey(13,textTE);
  903.     TECalText(textTE);
  904.     AdjustTextScrollBar();
  905.     SetPort(savePort);
  906. }
  907.  
  908.  
  909.  
  910.  
  911.  
  912. void Names()
  913. {
  914.     EntityName name;
  915.     short err, counter;
  916.     Handle buffer = 0L;
  917.     short found;
  918.     MPPParamBlock p;
  919.     char Entity[110];
  920.     
  921.     p.MPPioCompletion = 0L;
  922.     p.MPPioRefNum = mpp;
  923.     buffer = NewHandle(LOOKUPBUFSIZE);
  924.     if (!buffer) {
  925.         return;
  926.     }
  927.     Message("\pFindind Neighbors...");
  928.     HLock(buffer);
  929.     BlockMove("\pNeighborhood Watch",name.typeStr, 20L);
  930.     name.objStr[0] = 1;
  931.     name.objStr[1] = '=';
  932.     name.zoneStr[0] = 1;
  933.     name.zoneStr[1] = '*';
  934.     BlockMove(name.objStr,Entity,33L);
  935.     counter = Entity[0] + 1;
  936.     BlockMove(name.typeStr,&Entity[counter],33L);
  937.     counter += name.typeStr[0] + 1;
  938.     BlockMove(name.zoneStr,&Entity[counter],33L);
  939.     p.NBPinterval = 5;
  940.     p.NBPcount = 4;
  941.     p.NBPentityPtr = Entity;
  942.     p.NBPretBuffPtr = *buffer;
  943.     p.NBPretBuffSize = LOOKUPBUFSIZE;
  944.     p.NBPmaxToGet = LOOKUPBUFSIZE / 110;
  945.     p.NBPnumGotten = 0;
  946.     err = PLookupName(&p,false);
  947.     err = p.MPPioResult;
  948.     if (!err) {
  949.         found = p.NBPnumGotten;
  950.         for (counter = 0; counter < found; counter++)
  951.             err = myNBPExtract(*buffer,found,counter + 1,&name, &(users[counter]));
  952.             Message(name.objStr);
  953.     }
  954.     if (buffer)
  955.         DisposHandle(buffer);
  956.     buffer = 0L;
  957. }
  958.  
  959.  
  960.  
  961.  
  962.  
  963.  
  964.  
  965.  
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972. short myNBPExtract(char *buffer,int howMany,int which,EntityName *Name,AddrBlock *Addr)
  973. {
  974.     char *p;
  975.     register int index = 1, nameCounter = 0;
  976.     
  977.     p = buffer;
  978.     while ((index < which) && (index < howMany)) {
  979.         p += 5;    /* skip addr and enumerator */
  980.         p += (*p) + 1;    /* skip name */
  981.         p += (*p) + 1;    /* skip type */
  982.         p += (*p) + 1;    /* skip zone */
  983.         index++;
  984.     }
  985.     BlockMove(p,(Ptr) Addr,4L);
  986.     p += 5;
  987.     BlockMove(p,Name->objStr,33L);
  988.     p += (*p) + 1;
  989.     BlockMove(p,Name->typeStr,33L);
  990.     p += (*p) + 1;
  991.     BlockMove(p,Name->zoneStr,33L);
  992.     return(0);
  993. }
  994.  
  995.  
  996.  
  997.  
  998.  
  999.  
  1000.